Skip to content


ai  101  pytorch  classification  nvidia  cuda  install  tensorrt  yolo  ardupilot  None  ros2  dds  micro ros  xrce  sitl  plugin  SITL  debug  rangefinder  pymavlink  mavros  gazebo  distance sensor  system_time  timesync  cmake  gtest  ctest  cpp  c++  format  fmt  multithreading  spdlog  camera  coordinate system  orb  matching  opencv  build  transformation  computer vision  homography  optical flow  of  trackers  cv  cyclonedds  eprosima  fastdds  simulation  config  ignition  bridge  sdf  tips  ign-transport  sensors  lidar  aptly  apt  encryption  pgp  docker  git  bundle  github  hooks  pre-commit  lxd  container  lxc  x11  profile  vscode  marpit  presentation  marp  markdown  mermaid  video  ffmpeg  gstreamer  cheat-sheet  sdp  v4l2loopback  gi  snippets  cheat Sheet  python  asyncio  future  click  cli  numpy  project  template  black  isort  docs  project document  docstrings  flake8  linter  git-hook  mypy  unittest  pytest  pylint  mock  iterator  generator  logging  tuple  namedtuple  typing  annotation  pyzmq  zmq  msgpack  action  namespace  remap  control2  ros2_control  gdb  qos  tag  plugins  msg  node  zero-copy  shm  tutorial  algorithm  calibration  diff  pid  dev  colcon  colcon_cd  rpi  arm  qemu  settings  behavior  plot  visualization  debugging  diagnostic  diagnostics  tutorials  gst  math  apm  rat_runtime_monitor  web  rosbridge  vue  binding  discovery  gazebo-classic  launch  spawn  cook  gps  imu  ray  gazebo_ros_ray_sensor  ultrsonic  range  ultrasonic  gazebo classic  wrench  effort  odom  ign  gz  xacro  ros_ign  diff_drive  odometry  joint_state  argument  OpaqueFunction  DeclareLaunchArgument  LaunchConfiguration  tmux  nav  slam  test  rclpy  executor  MultiThreadedExecutor  SingleThreadedExecutor  param  dynamic-reconfigure  service  client  setup.py  package.xml  parameter  parameters  custom  msgs  executers  pub  sub  rqt  rviz  rviz2  pose  marker  tf2  deb  package  setup  local_setup  rosdep  package manager  project settings  vcstool  cross-compiler  nano  texture  tmuxp  rootfs  embedded  zah  linux  rm  ubuntu  ip  ss  network  netstat  snap  deploy  ssh  systemd  mkdocs  extensions  socat  networking  serial  udp  tc  mtu  select  px4  robotics  kalman_filter  kalman  filter  control  todo  vscode-ext  json  yaml  schema  yocto  poky  world  gazebo_ros2_control  position_controller  effort_controller  velocity_controller  urdf  gazebo_ros_force  gazebo_ros_joint_state_publisher  robot_state_publisher  joint_state_publisher  projects  vrx  buoyancy 

joint state with sdf


Table of Content

LAB#

  • load model SDF into ignition and rviz
  • publish JointState from ignition to ros2 using bridge
├── CMakeLists.txt
├── config
│   └── rviz.rviz
├── launch
│   └── ign.launch.launch.py
│   └── ign_bridge.launch.py
├── models
│   └── vehicle_2
│       │   └── meshes
│       │       └── robot_base.stl
│       └── model.config
│       └── model.sdf
├── worlds
│   └── vehicle.sdf
└── package.xml

launch#

ign#

import os

from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.actions import IncludeLaunchDescription, SetEnvironmentVariable
from launch.conditions import IfCondition
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node

PACKAGE_NAME = "ign_tutorial"
SDF_MODEL_NAME = "vehicle_2"
WORLD_NAME = "vehicle.sdf"

def generate_launch_description():
    sim_time_arg = DeclareLaunchArgument(
        "use_sim_time",
        default_value=["true"],
        description="Enable sim time from /clock",
    )
    with_bridge_arg = DeclareLaunchArgument(
        "with_bridge",
        default_value=["false"],
        description="Launch simulation with ros ign bridge",
    )

    pkg_ros_gz_sim = get_package_share_directory("ros_gz_sim")
    pkg = get_package_share_directory(PACKAGE_NAME)

    sdf_path = f"{pkg}/models/{SDF_MODEL_NAME}/model.sdf"
    use_sim_time = LaunchConfiguration("use_sim_time")

    resources = [os.path.join(pkg, "worlds"), os.path.join(pkg, "models")]
    resource_env = SetEnvironmentVariable(
        name="IGN_GAZEBO_RESOURCE_PATH", value=":".join(resources)
    )

    gazebo = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(
            os.path.join(pkg_ros_gz_sim, "launch", "gz_sim.launch.py")
        ),
        launch_arguments={"gz_args": f"-r -v 2 {WORLD_NAME}"}.items(),
    )

    # launch ign_bridge if with_bridge is true
    ign_bridge = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(
            os.path.join(pkg, "launch", "ign_bridge.launch.py"),
        ),
        launch_arguments={"use_sim_time": use_sim_time}.items(),
        condition=IfCondition(LaunchConfiguration("with_bridge"))
    )

    # robot state publisher node
    robot_state_publisher = Node(
        package="robot_state_publisher",
        executable="robot_state_publisher",
        output="screen",
        parameters=[
            {"use_sim_time": use_sim_time},
            {"robot_description": open(sdf_path).read()},
        ],
    )

    ld = LaunchDescription()
    ld.add_action(sim_time_arg)
    ld.add_action(with_bridge_arg)

    ld.add_action(resource_env)
    ld.add_action(gazebo)
    ld.add_action(ign_bridge)
    ld.add_action(robot_state_publisher)
    return ld

bridge#

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.conditions import IfCondition
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node

ROBOT_NAME = "basic_mobile_bot"

def generate_launch_description():
    use_sim_time_arg = DeclareLaunchArgument(
        "use_sim_time", default_value=["false"], description="use sim time from /clock"
    )

    namespace = ""
    use_sim_time = LaunchConfiguration("use_sim_time")
    ign_model_prefix = "/world/demo/model/" + ROBOT_NAME

    # clock bridge
    clock_bridge = Node(
        package="ros_gz_bridge",
        executable="parameter_bridge",
        namespace=namespace,
        name="clock_bridge",
        output="screen",
        arguments=["/clock@rosgraph_msgs/msg/Clock[ignition.msgs.Clock"],
        condition=IfCondition(use_sim_time),
    )

    # joint state bridge
    # /world/demo/model/v2/model/basic_mobile_bot/joint_state
    joint_state_bridge = Node(
        package="ros_gz_bridge",
        executable="parameter_bridge",
        namespace=namespace,
        name="joint_state_bridge",
        output="screen",
        parameters=[{"use_sim_time": use_sim_time}],
        arguments=[
            ign_model_prefix + "/joint_state"
            + "@sensor_msgs/msg/JointState"
            + "[ignition.msgs.Model"
        ],
        remappings=[(ign_model_prefix + "/joint_state", "/joint_states")],
    )

    ld = LaunchDescription()
    ld.add_action(use_sim_time_arg)
    ld.add_action(clock_bridge)
    ld.add_action(joint_state_bridge)
    return ld

tf tree#

ros2 run rqt_tf_tree rqt_tf_tree

sdf#

model#

model

world#

world

<include>
    <pose>0 0 1 0 0 0</pose>
    <uri>model://vehicle_2</uri>
</include>